<template>
  <a-modal
    title="高级查询构造器"
    :width="1200"
    :visible.sync="visible"
    :confirmLoading="confirmLoading"
    :maskClosable="false"
    @cancel="handleCancel"
  >
    <a-row style="margin-bottom: 12px;">
      <a-col :md="12" :xs="24">
        <a-form layout="inline">
          <a-form-item label="过滤条件">
            <a-select
              style="min-width: 240px"
              placeholder="请选择过滤条件"
              v-model="queryType"
              :getPopupContainer="node=>node.parentNode"
            >
              <a-select-option value="and">AND（所有条件都要求匹配）</a-select-option>
              <a-select-option value="or">OR（条件中的任意一个匹配）</a-select-option>
            </a-select>
          </a-form-item>
        </a-form>
      </a-col>
    </a-row>

    <a-row>
      <a-col :sm="24" :md="24-5">
        <!-- 查询条件构造 -->
        <a-form layout="inline">
          <a-row
            type="flex"
            style="margin-bottom:10px"
            :gutter="16"
            v-for="(item, index) in queryParams"
            :key="index"
          >
            <a-col :md="8" :xs="24" style="margin-bottom: 12px;">
              <a-select
                showSearch
                :filterOption="filterOption"
                placeholder="选择查询字段"
                style="width: 100%;"
                v-model="item.field"
                :getPopupContainer="node=>node.parentNode"
                @select="(val,option)=>handleSelected(option,item)"
              >
                <a-select-option
                  :key="index"
                  :value="it.value"
                  v-for="(it,index) in fieldList"
                >{{ it.label }}</a-select-option>
              </a-select>
            </a-col>

            <a-col :md="4" :xs="24" style="margin-bottom: 12px;">
              <a-select
                placeholder="匹配规则"
                style="width: 100%"
                :value="item.rule"
                :getPopupContainer="node=>node.parentNode"
                @change="handleRuleChange(item, $event)"
              >
                <a-select-option value="eq">等于</a-select-option>
                <a-select-option value="like">包含</a-select-option>
                <a-select-option value="right_like">以..开始</a-select-option>
                <a-select-option value="left_like">以..结尾</a-select-option>
                <a-select-option value="in">在...中</a-select-option>
                <a-select-option value="ne">不等于</a-select-option>
                <a-select-option value="gt">大于</a-select-option>
                <a-select-option value="ge">大于等于</a-select-option>
                <a-select-option value="lt">小于</a-select-option>
                <a-select-option value="le">小于等于</a-select-option>
              </a-select>
            </a-col>
            <a-col :md="8" :xs="24" style="margin-bottom: 12px;">
              <!--判断各种输入框-->
              <a-input
                v-if="item.rowType === 'input'"
                v-model="item.val"
                style="width: 100%"
                :placeholder="'请输入' + item.rowName"
              ></a-input>
              <a-input-number
                v-else-if="item.rowType === 'input-number'"
                v-model="item.val"
                style="width: 100%"
                :placeholder="'请输入' + item.rowName"
              ></a-input-number>
              <a-select
                v-else-if="item.rowType === 'select'"
                v-model="item.val"
                style="width: 100%"
                :placeholder="'请选择' + item.rowName"
              >
                <a-select-option :key="it.value" v-for="it in item.options">{{ it.label }}</a-select-option>
              </a-select>
              <a-select
                v-else-if="item.rowType === 'select-multiple'"
                v-model="item.val"
                mode="multiple"
                style="width: 100%"
                :placeholder="'请选择' + item.rowName"
              >
                <a-select-option :key="it.value" v-for="it in item.options">{{ it.label }}</a-select-option>
              </a-select>
              <a-date-picker
                :showTime="{ defaultValue: item.defaultTime }"
                v-else-if="item.rowType === 'date'"
                :placeholder="'请选择' + item.rowName"
                style="width: 100%"
                format="YYYY-MM-DD HH:mm:ss"
                v-model="item.val"
              ></a-date-picker>
              <a-input v-else>

              </a-input>
            </a-col>
            <a-col :md="4" :xs="0" style="margin-bottom: 12px;">
              <a-button @click="handleAdd" icon="plus"></a-button>&nbsp;
              <a-button v-show="fieldSize" @click="handleDel( index )" icon="minus"></a-button>
            </a-col>
          </a-row>
        </a-form>
      </a-col>
      <a-col :sm="24" :md="5">
        <!-- 查询记录 -->
        <a-card class="j-super-query-history-card" :bordered="true">
          <div slot="title">
            保存的查询
          </div>

          <a-empty v-if="saveTreeData.length === 0" class="j-super-query-history-empty" description="没有保存任何查询"/>
          <a-tree
            v-else
            class="j-super-query-history-tree"
            showIcon
            :treeData="saveTreeData"
            :selectedKeys="[]"
            @select="handleTreeSelect"
          >
          </a-tree>
        </a-card>
      </a-col>
    </a-row>


    <!-- 底部 -->
    <template slot="footer">
      <div style="float: left">
        <a-button :loading="confirmLoading" @click="handleReset">重置</a-button>
        <a-button :loading="confirmLoading" @click="handleSave">保存查询条件</a-button>
      </div>
      <a-button :loading="confirmLoading" @click="handleCancel">关闭</a-button>
      <a-button :loading="confirmLoading" type="primary" @click="handleOk">查询</a-button>
    </template>

    <a-modal title="请输入保存的名称" :visible="prompt.visible" @cancel="prompt.visible=false" @ok="handlePromptOk">
      <a-input v-model="prompt.value"></a-input>
    </a-modal>
  </a-modal>
</template>

<script>
import moment from 'moment'
import { mixinDevice } from '@/utils/mixin'
import * as utils from '@/utils/util'
import { axios } from '@/utils/request'
  export default {
    name: 'WSuperQuery',
    mixins: [mixinDevice],
    data() {
      return {
        moment,
        queryType: 'and',
        queryParams: [
          {
            field: undefined,
            rule: 'eq'
          }
        ],
        saveCodeBefore: 'JSuperQuerySaved_',
        treeIcon: <a-icon type="file-text"/>,
        prompt: {
          visible: false,
          value: ''
        },
        visible: this.showModel,
        // 保存查询条件的treeData
        saveTreeData: [],
        confirmLoading: false,
      }
    },
    props: {
      showModel: {
        type: Boolean,
        default: false
      },
      saveCode: {
        type: String,
        default: null
      },
      fieldList: {
        type: Array,
        required: true
      }
    },
    computed: {
      fieldSize () {
        return this.queryParams.length > 1
      },
      fullSaveCode() {
        let saveCode = this.saveCode
        if (saveCode == null || saveCode === '') {
          saveCode = this.$route.fullPath
        }
        return this.saveCodeBefore + saveCode
      }
    },
    watch: {
      showModel (newVal) {
        this.visible = newVal
      },
      // 当 saveCode 变化时，重新查询已保存的条件
      fullSaveCode: {
        immediate: true,
        handler() {
          let list = this.$ls.get(this.fullSaveCode)
          if (list instanceof Array) {
            this.saveTreeData = list.map(i => this.renderSaveTreeData(i))
          }
        }
      }
    },

    methods: {
      handleCancel () {
        this.visible = false
        this.$emit('ok')
      },
      // 处理选择的查询字段
      handleSelected (node, item) {
        const it = this.fieldList.find(it => it.value === item.field)
        item['rowType'] = it.type
        item['rowName'] = it.label
        if (it.options) {
          item['options'] = it.options
        }
        if (it.dicUrl) {
          axios({
            url: it.dicUrl,
            method: 'GET'
          }).then(res => {
            item['options'] = res.data
          })
        }
        this.$set(item, 'val', undefined)
      },
      // 置空
      handleReset() {
        this.queryParams = [{ field: undefined, rule: 'eq' }]
      },
      // 搜索类型
      handleRuleChange (item, newValue) {
        this.$set(item, 'rule', newValue)
      },
      // 添加搜索条件
      handleAdd () {
        this.queryParams.push({ rule: 'eq' })
      },
      // 删除搜索条件
      handleDel (index) {
        this.queryParams.splice(index, 1)
      },
      // 点击保存查询条件
      handleSave() {
        let params = this.removeEmptyQueryParam(this.queryParams)
        if (this.isNullArray(params)) {
          this.$message.warning('空条件不能保存')
        } else {
          this.prompt.value = ''
          this.prompt.visible = true
        }
      },
      // 真正的保存条件
      handlePromptOk() {
        let { value } = this.prompt
        if(!value){
          this.$message.warning('保存名称不能为空')
          return
        }
        // 取出查询条件
        let records = this.removeEmptyQueryParam(this.queryParams)
        // 判断有没有重名的
        let filterList = this.saveTreeData.filter(i => i.originTitle === value)
        if (filterList.length > 0) {
          this.$confirm({
            content: `${value} 已存在，是否覆盖？`,
            onOk: () => {
              this.prompt.visible = false
              filterList[0].records = records
              this.saveToLocalStore()
              this.$message.success('保存成功')
            }
          })
        } else {
          // 没有重名的，直接添加
          this.prompt.visible = false
          // 添加到树列表中
          this.saveTreeData.push(this.renderSaveTreeData({
            title: value,
            matchType: this.matchType,
            records: records
          }))
          // 保存到 LocalStore
          this.saveToLocalStore()
          this.$message.success('保存成功')
        }
      },
      /** 渲染保存查询条件的 title（加个删除按钮） */
      renderSaveTreeData(item) {
        item.icon = this.treeIcon
        item.originTitle = item['title']
        item.title = (arg1, arg2) => {
          let vNode
          // 兼容旧版的Antdv
          if (arg1.dataRef) {
            vNode = arg1
          } else if (arg2.dataRef) {
            vNode = arg2
          } else {
            return <span style="color:red;">Antdv版本不支持</span>
          }
          let {originTitle} = vNode.dataRef
          return (
            <div class="j-history-tree-title">
            <span>{originTitle}</span>

            <div class="j-history-tree-title-closer" onClick={e => this.handleRemoveSaveTreeItem(e, vNode)}>
        <a-icon type="close-circle"/>
            </div>
            </div>
        )
        }
        return item
      },
      handleRemoveSaveTreeItem(event, vNode) {
        // 阻止事件冒泡
        event.stopPropagation()

        this.$confirm({
          content: '是否删除当前查询？',
          onOk: () => {
            let { eventKey } = vNode
            this.saveTreeData.splice(Number.parseInt(eventKey.substring(2)), 1)
            this.saveToLocalStore()
          },
        })
      },
      // 将查询保存到 LocalStore 里
      saveToLocalStore() {
        let saveValue = this.saveTreeData.map(({ originTitle, matchType, records }) => ({ title: originTitle, matchType, records }))
        this.$ls.set(this.fullSaveCode, saveValue)
      },
      // 查询
      handleOk() {
        if (!this.queryType) {
          this.$message.error('请选择过滤条件')
          return
        }
        if (!this.isNullArray(this.queryParams)) {
          const params = this.removeEmptyQueryParam(this.queryParams)

          for (const param of params) {
            moment.locale('zh-cn')

            if (Array.isArray(param.val)) {
              param.val = param.val.join(',')
            } else if (param.rowType === 'date') {
              param.val = moment(param.val).format('YYYY-MM-DD HH:mm:ss')
            }
          }
          this.$emit('ok', this.queryType, params)
        } else {
          this.$message.error('不能查询空条件')
        }
      },
      // 工具类 判断是不是空数组对象
      isNullArray (array) {
        if (!array || array.length === 0) {
          return true
        }
        if (array.length === 1) {
          const obj = array[0]
          if (!obj.field || (obj.val == null || obj.val === '') || !obj.rule) {
            return true
          }
        }
        return false
      },
      // 查询字段搜索
      filterOption (input, option) {
        return (
          option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
        )
      },
      handleTreeSelect(idx, event) {
        if (event.selectedNodes[0]) {
          let { queryType, records } = event.selectedNodes[0].data.props
          // 将保存的matchType取出，兼容旧数据，如果没有保存就还是使用原来的
          this.queryType = queryType || this.queryType
          this.queryParams = utils.cloneObject(records)
        }
      },
      removeEmptyQueryParam (arr) {
        const array = JSON.parse(JSON.stringify(arr))
        for (let i = 0; i < array.length; i++) {
          const item = array[i]
          if (item == null || Object.keys(item).length <= 0 || !item.field) {
            array.splice(i--, 1)
          } else {
            delete item.rowName
            if (Array.isArray(item.options)) {
              delete item.options
            }
          }
        }
        return array
      }
    }
  }
</script>

<style lang="less" scoped>
.j-super-query-history-card {
  /deep/ .ant-card-body,
  /deep/ .ant-card-head-title {
    padding: 0;
  }

  /deep/ .ant-card-head {
    padding: 4px 8px;
    min-height: initial;
  }
}
.j-super-query-history-tree {

  .j-history-tree-title {
    width: calc(100% - 24px);
    position: relative;
    display: inline-block;

    &-closer {
      color: #999999;
      position: absolute;
      top: 0;
      right: 0;
      width: 24px;
      height: 24px;
      text-align: center;
      opacity: 0;
      transition: opacity 0.3s, color 0.3s;

      &:hover {
        color: #666666;
      }

      &:active {
        color: #333333;
      }
    }

    &:hover {
      .j-history-tree-title-closer {
        opacity: 1;
      }
    }

  }

  /deep/ .ant-tree-switcher {
    display: none;
  }

  /deep/ .ant-tree-node-content-wrapper {
    width: 100%;
  }
}


</style>